import type { RouteRecordRaw, Router } from 'vue-router';
import { isNavigationFailure } from 'vue-router';
import { useUserStoreWidthOut } from '@/store/modules/user';
import { useAsyncRouteStoreWidthOut } from '@/store/modules/asyncRoute';
import { useProjectSettingStore } from '@/store/modules/projectSetting';

// import { ACCESS_TOKEN } from '@/store/mutation-types';
import { storage } from '@/utils/Storage';
import { PageEnum } from '@/enums/pageEnum';
import { ErrorPageRoute } from '@/router/init';
import { t } from '@/i18n';
import { useWsStore } from '@/store/modules/ws';

// import { getMac } from '@/api/common';

const LOGIN_PATH = PageEnum.BASE_LOGIN;

const whitePathList = [LOGIN_PATH]; // no redirect whitelist

const wujie = (window as any).$wujie || null;

let reloadTime: any = null;

export function createRouterGuards(router: Router) {
  const userStore = useUserStoreWidthOut();

  const asyncRouteStore = useAsyncRouteStoreWidthOut();

  const projectStore = useProjectSettingStore();

  const wsStore = useWsStore();

  const $message = window['$message'];

  router.beforeEach(async (to, from, next) => {
    const Loading = window['$loading'] || null;
    !window['$wujie'] && Loading && Loading.start();

    const powers = userStore.powers || [];

    // const isGetApplication = userStore.isGetApplication || false;

    let routes = [];

    // if (!isGetApplication) {
    //   await userStore.getapplicationConfigList();
    // }

    const mac = projectStore.mac;

    if (window.electron) {
      if (!mac) {
        const res = await window.electron.getMac();

        const { host } = res.data;

        let sHost = storage.get('host');

        if (!sHost || host !== sHost) {
          storage.set('host', host);

          window.location.reload();

          next();

          return;
        }

        projectStore.setMacData(res.data);

        await projectStore.setMachineData(res.data);
      }
    } else {
      storage.set('host', window?.location?.hostname || 'localhost');
    }

    if (from.path === LOGIN_PATH && to.name === 'errorPage') {
      next(PageEnum.BASE_HOME);
      return;
    }

    // Whitelist can be directly entered
    if (whitePathList.includes(to.path as PageEnum)) {
      next();

      return;
    }

    const token = userStore.token || storage.get('access_token');

    if (!token) {
      // You can access without permissions. You need to set the routing meta.ignoreAuth to true
      if (to.meta.ignoreAuth) {
        next();

        return;
      }
      // redirect login page
      const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
        path: LOGIN_PATH,
        replace: true,
      };

      if (to.path) {
        redirectData.query = {
          ...redirectData.query,
          redirect: to.path,
        };
      }

      next(redirectData);

      return;
    }

    !wsStore.client && wsStore.initSocket();

    if (asyncRouteStore.getIsDynamicAddedRoute) {
      next();

      return;
    } else if (powers && powers.length) {
      routes = asyncRouteStore.filtergenerateRoutes(powers);
    } else {
      try {
        const userInfo: any = await userStore.getInfo();
        routes = await asyncRouteStore.generateRoutes(userInfo);
        // 判断如果是机长角色，则跳转到生产主页
        // 默认机长角色id = 2
        const { role = [] } = userInfo || {};
        const roleIds = role.map((item) => item.id);

        if (roleIds.includes('2')) {
          storage.set('collapsed', '1');
          next('/wip/productionCenter');
        } else {
          storage.set('collapsed', '0');
        }
      } catch (e) {
        next('/login');
        return;
      }
    }

    // 动态添加可访问路由表
    routes.forEach((item) => {
      router.addRoute(item as unknown as RouteRecordRaw);
    });

    // await router.replace(router.currentRoute.value.fullPath);

    // 添加404
    const isErrorPage = router.getRoutes().findIndex((item) => item.name === ErrorPageRoute.name);
    if (isErrorPage === -1) router.addRoute(ErrorPageRoute as unknown as RouteRecordRaw);

    const redirectPath = (from.query.redirect || to.path) as string;
    const redirect = decodeURIComponent(redirectPath);
    const nextData: any = to.path === redirect ? { ...to, replace: true } : { path: redirect };
    await asyncRouteStore.setDynamicAddedRoute(true);

    // await router.replace(to.path);

    // next();

    await next(nextData.fullPath || nextData.path);

    Loading && Loading.finish();
  });

  router.afterEach((to, _, failure) => {
    const title = `${t(`route.${to?.meta?.title as string}`) || document.title}`;

    const { fullPath = '' } = to;

    document.title = title;

    if (wujie) {
      if (fullPath !== '/dashboard/workplace') wujie?.bus.$emit('setPageTitleFn', title);

      if (fullPath === userStore.wujieRouterPath) {
        setTimeout(() => {
          wujie?.bus.$emit('equipmentAfterSalesWujieRouterLoadFn');
        }, 300);

        userStore.wujieRouterPath = '';
      }
    }

    if (isNavigationFailure(failure)) {
      // console.log('failed navigation', failure)
    }
    const asyncRouteStore = useAsyncRouteStoreWidthOut();
    // 在这里设置需要缓存的组件名称
    const keepAliveComponents = asyncRouteStore.keepAliveComponents;
    const currentComName: any = to.matched.find((item) => item.name === to.name)?.name;
    if (currentComName && !keepAliveComponents.includes(currentComName) && to.meta?.keepAlive) {
      // 需要缓存的组件
      keepAliveComponents.push(currentComName);
    } else if (!to.meta?.keepAlive || to.name === 'Redirect') {
      // 不需要缓存的组件
      const index = asyncRouteStore.keepAliveComponents.findIndex(
        (name) => name === currentComName
      );
      if (index !== -1) keepAliveComponents.splice(index, 1);
    }
    asyncRouteStore.setKeepAliveComponents(keepAliveComponents);
    const Loading = window['$loading'] || null;
    Loading && Loading.finish();
  });

  router.onError((error) => {
    // const pattern = /Loading chunk .+ failed/g;

    // const isChunkLoadFailed = error.message.match(pattern);

    // console.log(error);

    // console.log(typeof error.message);

    if (error) {
      $message.warning(t('common.tipMsg.isChunkLoadFailed'));

      if (!reloadTime) {
        reloadTime = setTimeout(() => {
          location.reload();
        }, 3000);
      }
    }

    // console.log(error.message);

    // console.log(error, '路由错误');
  });
}
